Apple, the Apple logo, and Macintosh are registered trademarks of Apple Computer, Inc.
Mac and OpenDoc are trademarks of Apple Computer, Inc.
FlipEnd is a utility to manipulate the endianess of memory. Specifically, FlipEnd performs byte-swapping on two and four byte values, or arrays and structures of two or four byte values. More generally, FlipEnd can be used to ensure data written to a persistent store (file, storage unit, etc.) is written in a standard format so the persistent store can be used correctly cross platform.
The standard format for FlipEnd is little endian, as opposed to big endian. So using FlipEnd to coerce data into "standard" format means you are writing data in little endian format.
The following is a gratuitous definition of precisely what is meant by endianess. Multibyte (two or four byte, etc.) values have a processor dependent layout when one considers the relationship between value bit-ordering and address byte-ordering. A four byte value contains 32 bits which (conceptually) either ascend or descend in significance. When the bits cross byte boundaries, the ordering can be observed by examining each byte separately. On a big endian platform, bytes are ordered in decreasing significance, and on a little endian platform, bytes are ordered in increasing significance. Consider the four byte value 0x87654321. In big endian format, the bytes of this value in memory occur: 0x87 0x65 0x43 0x21. But in little endian format, the bytes of this value in memory occur: 0x21 0x43 0x65 0x87. A problem occurs when writing a multibyte value from memory (a byte stream) to any other byte stream (e.g. disk) which is accessible to a processor on another platform which uses the opposite endianess. Unless care is taken, the usefulness of every multibyte value can be destroyed by inverting the ordering of bytes.
One way to deal with this is to change multibyte values in memory to a specific standard cross platform format before writing the value to a persistent byte stream like disk storage. Then when the multibyte values are read from the persistent store, the reading platform can convert them from standard back to platform format before using them. The FlipEnd utility provides this service, and the resulting code works correctly without changes on different platforms.
FlipEnd clients must stay aware of whether values are in the platform format state, or in the standard format state, and avoid operations on values in standard format other than reading and writing them to byte streams or converting them to platform format. Typically values are only in standard format in routines handling i/o to a persistent store.
Platform
FlipEnd assumes that big endian platforms will define the compiler switch _PLATFORM_BIG_ENDIAN_. FlipEnd will not perform as advertised on big endian platforms unless this switch is defined. This switch affects the definition of macros for conversion to and from standard format.
Flipping Routines
FlipEnd clients typically do not use the following functions directly, because these functions always swap bytes whether it is appropriate to do so or not on the current platform. Instead, clients normally use the macros in the next section which convert to and from standard format.
ODUShort ODFlipShort(ODUShort n);
Converts a single 2-byte integer to the opposite endianess.
void ODFlipShortArray(ODUShort* a, unsigned long count);
Modifies an array of count 2-byte integers to the opposite endianess.
ODULong ODFlipLong(ODULong n);
Converts a single 4-byte integer to the opposite endianess.
void ODFlipLongArray(ODULong* a, unsigned long count);
Modifies an array of count 4-byte integers to the opposite endianess.
Inverts the endianess of the contents of memory in structure according tothe layout described by groups, which should be a zero-terminated array of shorts, where each short describes the size of the next chunk of memory in structure to be processed. A negative value -x in the groups array indicates a block of endianess-neutral memory, like a string, and causes x bytes of memory in structure to be skipped over without conversion. A positive value x in the groups array indicates an x byte block of memory in structure which should have it's bytes flipped end for end. Only positive values in the set { 2, 4, 8 } are handled. (Other positive values are handled like negative values: space is skipped unchanged.) For example:
struct Foo {
long beta;
char gamma[8];
long delta;
short alpha;
};
const short fooGroups[] = {
4, // beta
-8, // gamma
4, // delta
2, // alpha
0, // zero-termination
};
Macros
The following macros provide the expected way for FlipEnd clients to convert values to and from standard format. On big endian platforms, these macros call the appropriate byte-swapping functions described in the previous section. On little endian platforms, these macros effectively do nothing at all, and return the same values that were passed in. Note that while the "from standard" and "to standard" forms of the macros are actually identical, the two different forms help clarify the current state (platform or standard) of the values being manipulated.
ODUShort ConvertODUShortToStd(ODUShort n);
ODUShort ConvertODUShortFromStd(ODUShort n);
ODSShort ConvertODSShortToStd(ODSShort n);
ODSShort ConvertODSShortFromStd(ODSShort n);
Converts a single signed or unsigned 2-byte integer to the opposite endianess.
void ConvertODUShortArrayToStd(a,c);
void ConvertODUShortArrayFromStd(a,c);
void ConvertODSShortArrayToStd(a,c);
void ConvertODSShortArrayFromStd(a,c);
Modifies an array of count signed or unsigned 2-byte integers to the opposite endianess.
ODULong ConvertODULongToStd(ODULong n);
ODULong ConvertODULongFromStdODULong (n);
ODSLong ConvertODSLongToStd(ODSLong n);
ODSLong ConvertODSLongFromStd(ODSLong n);
Converts a single signed or unsigned 4-byte integer to the opposite endianess.
void ConvertODULongArrayToStd(ODULong* a, unsigned long count);
void ConvertODULongArrayFromStd(ODULong* a, unsigned long count);
void ConvertODSLongArrayToStd(ODSLong* a, unsigned long count);
void ConvertODSLongArrayFromStd(ODSLong* a, unsigned long count);
Modifies an array of count signed or unsigned 4-byte integers to the opposite endianess.
Inverts the endianess of the contents of memory in structure according tothe layout described by groups. See ODFlipStruct() in the previous section for details.